package main

import "fmt"

type chain struct {
	next *chain
	data string
}

func NewChain(data string, c *chain) *chain {
	return &chain{
		data: data,
		next: c,
	}
}

type headNode struct {
	length int
	next   *chain
}

func NewHeadNode() *headNode {
	return &headNode{}
}

func (n *headNode) Push(data string) {
	c := NewChain(data, n.next)
	n.next = c
	n.length++

}

func (n *headNode) Pop() (data string, ok bool) {
	if n.length <= 0 {
		return "", false
	}
	c := n.next
	n.next = c.next
	n.length--

	return c.data, true
}

func (n *headNode) StackEmpty() bool {
	if n.length > 0 && n.next != nil {
		return false
	}
	return true
}

func (n *headNode) GetTop() (string, bool) {
	if n.length > 0 && n.next != nil {
		return n.next.data, true
	}
	return "", false
}

func (n *headNode)ClearStack() {
	n.next = nil
	n.length = 0
}

func (n *headNode) Traverse(){
	c := n.next
	for{
		if c == nil {
			return
		}
		fmt.Println(c.data)
		c = c.next
		
	}
}

func (n *headNode) QueueLength() int {
	return n.length
}

func main() {
	c := NewHeadNode()
	c.Push("1")
	c.Push("2")
	c.Push("3")
	c.Push("4")
	c.Push("5")

	fmt.Println(c.StackEmpty())
	fmt.Println(c.QueueLength())
	c.Traverse()
	fmt.Println(c.Pop())
	fmt.Println(c.Pop())
	fmt.Println(c.StackEmpty())
	fmt.Println(c.QueueLength())
	c.Traverse()
	fmt.Println(c.GetTop())
	fmt.Println(c.StackEmpty())
	fmt.Println(c.QueueLength())
	c.Traverse()
	c.ClearStack()
	fmt.Println(c.StackEmpty())
	fmt.Println(c.QueueLength())
	c.Traverse()
}
